/* * Copyright [1999-2015] Wellcome Trust Sanger Institute and the EMBL-European Bioinformatics Institute * Copyright [2016-2017] EMBL-European Bioinformatics Institute * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.ensembl.healthcheck.eg_gui; import java.awt.Component; import java.awt.dnd.DnDConstants; import java.awt.dnd.DragGestureRecognizer; import java.awt.dnd.DragSource; import java.awt.dnd.DropTarget; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.swing.JTree; import javax.swing.ListSelectionModel; import javax.swing.border.Border; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreePath; import javax.swing.tree.TreeSelectionModel; import org.ensembl.healthcheck.DatabaseRegistry; import org.ensembl.healthcheck.GroupOfTests; import org.ensembl.healthcheck.TestInstantiator; import org.ensembl.healthcheck.configuration.ConfigureHost; import org.ensembl.healthcheck.eg_gui.dragAndDrop.ListOfTestsToBeRunDropListener; import org.ensembl.healthcheck.eg_gui.dragAndDrop.TestsTransferHandler; import org.ensembl.healthcheck.eg_gui.dragAndDrop.TreeOfTestGroupsGestureListener; import org.ensembl.healthcheck.testcase.EnsTestCase; import org.ensembl.healthcheck.util.DBUtils; /** * * <p> * Collection of static methods for building the GUI components. This class * is stateless. Holds code that would clutter up GuiGroupTestRunnerFrame * otherwise. * </p> * * @author michael * */ public class GuiTestRunnerFrameComponentBuilder { public static Border defaultEmptyBorder = BorderFactory.createEmptyBorder(12, 4, 12, 4); public static Component createLeftJustifiedComponent(Component c) { Box box = Box.createHorizontalBox(); box.add(c); box.add(Box.createHorizontalGlue()); return box; } public static Component createLeftJustifiedText(String text) { JLabel t = new JLabel(text, JLabel.LEFT); t.setAlignmentX(JLabel.LEFT_ALIGNMENT); return createLeftJustifiedComponent(t); } public static JComboBox createDbServerSelector(List<ConfigureHost> dbDetails) { List<String> dbServerComboBoxDisplayName = new ArrayList<String>(); // Sort items in list by hostname then by user. // Collections.sort(dbDetails, new Comparator<ConfigureHost>() { @Override public int compare(ConfigureHost o1, ConfigureHost o2) { int comparisonResult = o1.getHost().compareTo(o2.getHost()); if (comparisonResult!=0) { return comparisonResult; } return ( o1.getUser().compareTo(o2.getUser()) ) ; } }); for (ConfigureHost currentDbServer : dbDetails) { if (currentDbServer.getHost().equals("127.0.0.1")) { // If the connection is local, it is probably being port // forwarded. Add port number so the user knows which one // it is. // dbServerComboBoxDisplayName.add( currentDbServer.getHost() + ":" + currentDbServer.getPort() + " as " + currentDbServer.getUser() ); } else { dbServerComboBoxDisplayName.add( currentDbServer.getHost() + " as " + currentDbServer.getUser() ); } } JComboBox dbServerSelector = new JComboBox(dbServerComboBoxDisplayName.toArray()); return dbServerSelector; } /** * * <p> * Shamelessly copied this useful method from page 605 of Learning Java * from O'Reilly. * </p> * * @param label * @return menu item for label/action * */ public static JMenuItem makeMenuItem(String label, ActionListener a, String actionCommand) { JMenuItem item = new JMenuItem(label); item.addActionListener(a); item.setActionCommand(actionCommand); return item; } public static JPopupMenu createTreeOfTestGroupsPopupMenu(ActionListener a) { final JPopupMenu popup = new JPopupMenu(); popup.add(makeMenuItem("Add to tests to be run", a, Constants.Add_to_tests_to_be_run)); return popup; } public static JPopupMenu createListOfTestsToBeExecutedPopupMenu(ActionListener a) { final JPopupMenu popup = new JPopupMenu(); popup.add(makeMenuItem("Remove selected tests", a, Constants.REMOVE_SELECTED_TESTS)); popup.add(makeMenuItem("Run selected tests", a, Constants.RUN_SELECTED_TESTS)); popup.add(makeMenuItem("Run all tests", a, Constants.RUN_ALL_TESTS)); return popup; } /** * * <p> * Builds the JTree with the testgroups from which the user can select * the tests to be run. * </p> * * @param testGroupList * @return JTree * */ public static JTree createTreeOfTestGroups(List<GroupOfTests> testGroupList, JPopupMenu popup) { JTree tree = new JTree( TreeModelFromListOfGroupsBuilder.GroupOfTestsToTreeModel(testGroupList) ) { public String getToolTipText(MouseEvent evt) { if (getRowForLocation(evt.getX(), evt.getY()) == -1) return null; TreePath curPath = getPathForLocation(evt.getX(), evt.getY()); if (curPath.getLastPathComponent() instanceof TestNode) { return ((TestNode) curPath.getLastPathComponent()).getToolTipText(); } if (curPath.getLastPathComponent() instanceof GroupNode) { return ((GroupNode) curPath.getLastPathComponent()).getToolTipText(); } return "No tooltip text"; } }; tree .getSelectionModel() .setSelectionMode( TreeSelectionModel.SINGLE_TREE_SELECTION ); if (popup!=null) { tree.setComponentPopupMenu(popup); } // Must be set or the getToolTipText method will never be called. // tree.setToolTipText(""); DragSource ds = new DragSource(); DragGestureRecognizer dgr = ds.createDefaultDragGestureRecognizer( tree, DnDConstants.ACTION_COPY, new TreeOfTestGroupsGestureListener( tree, ds ) ); return tree; } /** * <p> * Creates the area in which the tests that will be run are listed. * </p> * * @param testInstantiator * @return area for list * */ public static JList createListOfTestsToBeRunArea( TestInstantiatorDynamic testInstantiator, JPopupMenu popup, final ActionListener al ) { JList listOfTestsToBeRun = new TestClassList(TestClassList.TestClassListToolTipType.DESCRIPTION); listOfTestsToBeRun.setToolTipText(""); listOfTestsToBeRun.setTransferHandler(new TestsTransferHandler()); listOfTestsToBeRun.setComponentPopupMenu(popup); // // Prevents the user from selecting multiple intervals. Removing // multiple intervals from the list does not work properly in // ActionExecution.removeSelectedTests and I don't see why, so I do // not allow selecting like that it here. // listOfTestsToBeRun.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); listOfTestsToBeRun.setCellRenderer(new TestCaseCellRenderer()); listOfTestsToBeRun.addKeyListener( new KeyListener() { @Override public void keyPressed(KeyEvent arg0) { // Backspace or delete button can be used to remove // selected tests. // boolean removeTestsKeyPressed = (arg0.getKeyCode()==KeyEvent.VK_DELETE) || (arg0.getKeyCode()==KeyEvent.VK_BACK_SPACE); if (removeTestsKeyPressed) { al.actionPerformed( new ActionEvent( this, 0, Constants.REMOVE_SELECTED_TESTS ) ); } } @Override public void keyReleased(KeyEvent arg0) {} @Override public void keyTyped (KeyEvent arg0) {} } ); DropTarget dt = new DropTarget( listOfTestsToBeRun, new ListOfTestsToBeRunDropListener( listOfTestsToBeRun, testInstantiator ) ); return listOfTestsToBeRun; } /** * <p> * Creates the button used to delete tests from the list of tests to be * run. * </p> * * @param buttonActionListener * @return button * */ public static JButton createRemoveSelectedTestsButton(ActionListener buttonActionListener) { JButton removeSelectedTestsButton = new JButton("Remove selected tests"); removeSelectedTestsButton.setMnemonic(KeyEvent.VK_R); removeSelectedTestsButton.setActionCommand(Constants.REMOVE_SELECTED_TESTS); removeSelectedTestsButton.addActionListener(buttonActionListener); removeSelectedTestsButton.setSize( Constants.DEFAULT_BUTTON_WIDTH, Constants.DEFAULT_BUTTON_HEIGHT ); return removeSelectedTestsButton; } /** * <p> * Creates the button used to run all tests from the list of tests to be * run. * </p> * * @param buttonActionListener * @return button * */ public static JButton createRunAllTestsButton(ActionListener buttonActionListener) { JButton button = new JButton("Run all tests"); button.setActionCommand(Constants.RUN_ALL_TESTS); button.addActionListener(buttonActionListener); button.setMnemonic(KeyEvent.VK_A); button.setSize( Constants.DEFAULT_BUTTON_WIDTH, Constants.DEFAULT_BUTTON_HEIGHT ); return button; } public static JButton createRunSelectedTestsButton(ActionListener buttonActionListener) { JButton button = new JButton("Run selected tests"); button.setActionCommand(Constants.RUN_SELECTED_TESTS); button.addActionListener(buttonActionListener); button.setMnemonic(KeyEvent.VK_S); button.setSize( Constants.DEFAULT_BUTTON_WIDTH, Constants.DEFAULT_BUTTON_HEIGHT ); return button; } /** * * <p> * Dummy ActionListener that only prints command names to STDOUT. * </p> * * @return listener instance * */ public static ActionListener createDummyActionListener() { return new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { System.out.println("Actioncommand received: " + arg0.getActionCommand()); } }; } }